home *** CD-ROM | disk | FTP | other *** search
/ Scene 96 / Scene 96 International Edition (Zyklop Software) (Disc 2) (1997).iso / misc / coding / mbphong / ephong4m.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-29  |  29.2 KB  |  1,308 lines

  1. // Real-time Transparent Motion-blurred phong environment mapping
  2. // Rex Deathstar/WaterLogic, July 1995
  3. // email me : deathstr@singnet.com.sg
  4. // BBS HQ   : Developer's Site BBS (065-561-0237)
  5.  
  6. // released to FTP.CDROM.COM and Developer's Site BBS (Singapore)
  7.  
  8. // remember to read the README.1ST file! :)
  9.  
  10. // Use SPACEBAR to start/stop your object from rotating and see how the
  11. // motion blur work its magic.
  12.  
  13. // TO COMPILE :
  14. // Use Borland C/C++ v3.1 and Small memory model, turn off all compiler
  15. // optimizations (it sux anyway :)
  16.  
  17. // IMPORTANT! :
  18. // These codes are really not what I'd call 'nice, well-behaved, concise'.
  19. // There're no comments, too many global variables, no dynamic memory
  20. // allocation, polygon code has no clipping and no sub-pixelling, and I used
  21. // the BSWAP 486 instruction for the fun of it, the 3D rotation has low
  22. // accuracy and is only on 2-axis, no aspect ratio adjustment, inaccurate
  23. // sorting.
  24. // The fact that it was written SOOO long ago, and becoz it was my first
  25. // attempt in 3D, please forgive me :)
  26. // The only things I think you can learn from this code are the motion blur,
  27. // transparency and arcsine corrected environment mapping.
  28. //
  29. // IMPORTANT! :
  30. // This code is for READING purposes, not to be cut and pasted into your
  31. // own demo/program/whatever. Doing so will qualify you as a $uperlemur, and
  32. // you'd have BETRAYED the TRUST of all who releases source codes for the
  33. // benefit of others, and it will make us decide not to release more source
  34. // codes and therefore all who want to learn will hate you. :)
  35.  
  36. // To Scene95:
  37. // yes, this is another left out routine from <u know what demo> :)
  38.  
  39. // Greetings time! :
  40. // C:> dir/w/s *.* | greet.exe
  41.  
  42. // Special Dedication! :                                           
  43. // brandon shen/pandemonium : nope, you got no rights to ban anyone from any
  44. //                            demo party unless you're god :)
  45. //                            and sorry, you cant make me withdraw
  46. //                            from scene 96 unless you're my dad ;)
  47. //                            yes, i hope u win something unless i'm not ur
  48. //                            friend :P
  49. //                            (yes i'm dead serious)
  50.  
  51. // trepaan : fuck you for writing a trojan virus demo! u made so many people
  52. //           suffer needlessly!
  53. // iguana : love you for all your help and belief that releasing source codes
  54. //          does work :)
  55. // ARM : thank you for all the enlightenment
  56. // jmagic : thank you for all your inspirations
  57. // orange : admire you for all the creativity
  58. // wili : owe you for all your tremendous help
  59. // MFX : worship you for the first realtime raytraced demo
  60.  
  61. // Special Tributes! :
  62. // .....Complex/Orange/Halcyon/NoooN/CNCD/Plant/KLF/Iguana/MFX/Valhalla.....
  63.  
  64. //                      WaterLogic productions
  65. //===========================================================================
  66. //............................Year 1994......................................
  67. //1.  REXINTRO.ZIP....debut selftro
  68.  
  69. //2.  ASYLUM!.ZIP ....Advert for Asylum BBS (closed down now :( )
  70.  
  71. //3.  ICHIBAN!.ZIP....Advert for IchiBan BBS
  72.  
  73. //4.  ANARCHY!.ZIP....Advert for Anarchy Online BBS
  74.  
  75. //5.  ICHIBAN2.ZIP....2nd Advert for IchiBan BBS
  76.  
  77. //6.  COROM.ZIP   ....Advert for COROM PRODUCTIONS BBS
  78.  
  79. //...........................Year 1995.......................................
  80. //7.  _FACES.ZIP  ....Slideshow demo featuring realtime crossfading
  81.  
  82. //8.  TINIFIRE.ZIP....76 byte fire routine, real small huh? (Full sources)
  83.  
  84. //9.  TINYSTAR.ZIP....123 byte 3D starfield, another small one. (Full sources)
  85.  
  86. //10. DELAYDOT.ZIP....3D object morph with delaydots. (Full sources)
  87.  
  88. //11. PARTICLE.ZIP....3D Lissajous figures morph. (Full sources)
  89.  
  90. //12. PURENESS.ZIP....1st place megademo during 'The Scene 95' demo party at
  91. //                    Seaview Hotel/Singapore on 2nd July 1995.
  92.  
  93. //13. COROMSRC.ZIP....Source codes to a BBS advert
  94.  
  95. //14. WATERFAL.ZIP....Source codes to a waterfall effect as seen in REXINTRO.
  96.  
  97. //............................Year 1996......................................
  98. //15. PLASWARP.ZIP....Source codes to the plasma and image warp effect as
  99. //                    seen in Pureness (needs PURENESS.DAT to run)
  100.  
  101. //16. DEVSITE!.ZIP....BBS advert for Developer's Site BBS, now WaterLogic's
  102.                       HQ. Features SVGA 3D motion blur.
  103.  
  104. //16. AGEN-ART.ZIP....High-res JPGs of Agen's art seen in Pureness
  105.  
  106. //17. STARGATE.ZIP....Source codes to the texture-mapped wormhole seen
  107. //                    in Pureness.
  108.  
  109. //18. MODELIST.ZIP....Generic VESA graphic mode lister with sources in C
  110.  
  111. //19. VOXELSPC.ZIP....Source codes to a fast height&color interpolated
  112. //                    Voxel landscape routine
  113.  
  114. //20. MPHONG.ZIP......Full sources to transparent motion-blur phong effect
  115.  
  116. //21. D???????.ZIP....Megademo for 'The Scene 96'!
  117. //                    Will be released on 2nd June 1996.
  118. //                    Features my new demo system 'EXP24'
  119.  
  120.  
  121.  
  122. #pragma inline
  123. asm    .486
  124.  
  125.  
  126. #include <conio.h>
  127. #include <math.h>
  128. #include <stdlib.h>
  129. #include <stdio.h>
  130. #include <dos.h>
  131. #include <process.h>
  132.  
  133. //-Phong parameters-//
  134. float    SPECULIAR_COEF;     // Speculiar coefficient
  135. float   SPECULIAR_EXPONENT; // Speculiar exponent
  136. float   DIFFUSE  ;          // Diffuse coefficient
  137. float   AMBIENCE ;          // Ambient light amount
  138. //------------------//
  139.  
  140. int            _3DXFORM=1;    // Flag to do 3D rotations
  141. #define        MAXVERTEX    750
  142. #define        MAXFACE        1400
  143. #define        rad        0.01745329
  144. #define        MAX        1300    // 3D rotation angle resolution
  145. #define        START_SCANLINE     0    // Screen scanline to start render
  146. #define        END_SCANLINE       200    // Screen scanline to end render
  147. #define        X    0
  148. #define        Y    1
  149. #define        Z    2
  150. #define        LEFT_ENTRY 0
  151. #define        RITE_ENTRY 4
  152. #define        unitScale    127.0    // scale of unit vector
  153. #define        pixelScale    191.0    // No.of colors used in palette
  154. #define        arccos_size     256
  155. #define        VERTEXfile     "VERTEX.DAT"
  156. #define     FACETfile      "FACET.DAT"
  157. #define        VNORMfile    "VNORM.DAT"
  158. #define     PALfile           "EPHONGM.PAL"
  159. #define        NBINS        400
  160. #define        BINSIZE        64
  161. #define        BINSIZELOG2    6
  162. #define        BLUR_LEVEL    1
  163. #define        MATRIX3D_RESOLUTION 10
  164.  
  165.     char    palette[768],phong[768],bmp_palette[1024];
  166.  
  167. unsigned int    vbuffer,order,backdrop,texture,alpha,vram=0xa000;
  168.     int    a,b,c,d,n,v,temp,dummy,loop_length;
  169.     int    wait,wait2,nframes,*temp_ptr;
  170.  
  171.     int    VERTEX,FACE;    //No.of Vertices and Facets in object
  172.     int    object[MAXVERTEX][3];
  173.     int    pt[MAXVERTEX][4],facet[MAXFACE][3],current_bin;
  174.     long    vnorm32[MAXVERTEX][3];
  175.     int    vnorm[MAXVERTEX][3],vnorm2[MAXVERTEX][3],*vnormal;
  176.     char    arccos[arccos_size],asine[256];
  177.  
  178. unsigned int     idx,idx1,idx2,y_offset[200],phong_curve[256],jmptable[256];
  179.     int    dud1[350],slope[800],dud2[350],top,bot,ysize;
  180.     int    p1x,p1y,p2x,p2y,p3x,p3y,flipflop;
  181.     int    v1,v2,w1,w2,i1,i2,i3;
  182.  
  183.     int    sinf[MAX],cosf[MAX],xsin,xcos,ysin,ycos,zsin,zcos;
  184.     int    temp_x,temp_y,temp_z;
  185.     int    rx,ry,rz,rx_dir,ry_dir,rz_dir,key;
  186.     int    DDAtx,DDAty,texture_x,texture_y,DDAx;
  187.  
  188. asm backdrop_file db 'phong7-1.bmp',0
  189. //asm texture_file  db 'texture.dat',0
  190. asm texture_file db 'envmap.bmp',0
  191. #define BMP
  192.  
  193. //#define BLACK_BACKDROP
  194. #define BLACK_VALUE 0
  195.  
  196. //||||||||||||||||||
  197. //||| PROTOTYPES |||
  198. //||||||||||||||||||
  199. void    graphics();
  200. void    text();
  201. void     init3d_10bits();
  202. void    make_phong_table();
  203. void    load_object();
  204. void    do_3D_transformation();
  205. void    sort_facets();
  206. void    move_light_source();
  207. void    draw_object_envmap();
  208. void     calc_slope();
  209. void    show_buffer();
  210. void    debug();
  211. void    load_texture();
  212. void    load_backdrop();
  213. void    apply_env_map_coord();
  214.  
  215. //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  216. //|||                          MAIN FUNCTION                             |||
  217. //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  218. void main()
  219. {
  220.     if(allocmem(4096,&vbuffer)!=-1) exit(1);
  221.     if(allocmem(4096,&order)!=-1) exit(1);
  222.     if(allocmem(4000,&backdrop)!=-1) exit(1);
  223.     if(allocmem(4096,&texture)!=-1) exit(1);
  224.     if(allocmem(4096,&alpha)!=-1) exit(1);
  225.  
  226.     load_object();
  227.     load_texture();
  228.     load_backdrop();
  229.  
  230.     #ifndef BMP
  231.     puts("RealTime 3D renderer using Metal Environment mapping");
  232.     puts("Rex Deathstar, July 1995");
  233.     printf("\nEnter Speculiar Coefficient:");
  234.     scanf("%f",&SPECULIAR_COEF);
  235.     printf("\nEnter Speculiar Exponent:");
  236.     scanf("%f",&SPECULIAR_EXPONENT);
  237.     printf("\nEnter Diffuse Component:");
  238.     scanf("%f",&DIFFUSE);
  239.     printf("\nEnter Ambience amount:");
  240.     scanf("%f",&AMBIENCE);
  241.         #endif
  242.  
  243.     init3d_10bits();
  244.     make_phong_table();
  245.     randomize();
  246.     graphics();
  247.  
  248. //---------------------------MAIN LOOP-------------------------------------
  249. MAIN_LOOP:;
  250. while(!kbhit())
  251. {
  252.     if(_3DXFORM==1) do_3D_transformation();
  253.     sort_facets();
  254.     apply_env_map_coord();
  255.     draw_object_envmap();
  256.     show_buffer();
  257.     nframes++;
  258. }
  259. //-------------------------------------------------------------------------
  260.     key=getch();
  261.     if(key==' ') { _3DXFORM*=-1; goto MAIN_LOOP; }
  262.     asm    mov    ax,3
  263.     asm    int    0x10
  264.  
  265.     printf("No.of frames drawn:%d",nframes);
  266. }
  267.  
  268. //|||||||||||||||||||||||||||||||||||
  269. //||| COPY VIRTUAL BUFFER TO VRAM |||
  270. //|||||||||||||||||||||||||||||||||||
  271. void    show_buffer()
  272. {
  273.     //copy buffer to screen
  274.     asm mov dx,0x3da
  275.     vr1:
  276.     asm in al,dx
  277.     asm test al,8
  278.     asm jnz vr1
  279.     /*vr2:
  280.     asm in al,dx
  281.     asm test al,8
  282.     asm jz vr2*/
  283.  
  284.     /*asm    mov    ax,0xa000
  285.     asm    mov    es,ax
  286.     asm    push    ds
  287.     asm    mov    ds,[vbuffer]
  288.     asm    mov    cx,64000/4
  289.     asm    xor    di,di
  290.     asm    xor    si,si
  291.     asm    rep    movsd
  292.     asm    pop    ds
  293.  
  294.     //clear buffer
  295.     asm    mov    es,[vbuffer]
  296.     asm    push    ds
  297.     asm    mov    ds,[backdrop]
  298.     asm    mov    cx,64000/4
  299.     asm    xor    di,di
  300.     asm    xor    si,si
  301.     asm    xor    eax,eax
  302.     asm    rep    movsd
  303.     asm    pop    ds*/
  304.  
  305.     // transparent motion blur,
  306.     // composites 'vbuffer' with 'alpha', then with 'texture'
  307.     asm mov di,64000
  308.     asm mov es,[alpha]
  309.     asm mov fs,[backdrop]
  310.     asm mov gs,[vram]
  311.     asm push ds
  312.     asm mov ds,[vbuffer]
  313.     asm xor cx,cx
  314.  
  315.     composite:
  316.     asm mov ax,[di]        // get 2 pixels from 'vbuffer'
  317.     asm mov dx,es:[di]    // get 2 pixels from 'alpha'
  318.     asm mov bx,dx
  319.  
  320.     //PIXEL #1
  321.     asm and al,al        // is this pixel drawn? (during phongfill())
  322.     asm jz  skipper0    // nope, skip it
  323.     asm add bl,al        // composite with pixel in 'alpha'
  324.     asm rcr bl,1        // average it, rcr=2 cycles on 486
  325.     asm mov [di],cl        // clear 'vbuffer'
  326.  
  327.     skipper0:
  328.     // motion blur, reduce intensity of expired samples
  329.     asm sub bl,BLUR_LEVEL
  330.     asm jnc not_negative0    // less than zero?
  331.     asm xor bl,bl        // overflow, clear pixel
  332.     not_negative0:
  333.  
  334.  
  335.     //PIXEL #2
  336.     asm and ah,ah        // is this pixel drawn? (during phongfill())
  337.     asm jz  skipper1    // nope, skip it
  338.     asm add bh,ah        // composite with pixel in 'alpha'
  339.     asm rcr bh,1        // average it
  340.     asm mov [di+1],cl    // clear 'vbuffer'
  341.  
  342.     skipper1:
  343.     // motion blur, reduce intensity of expired samples
  344.     asm sub bh,BLUR_LEVEL
  345.     asm jnc not_negative1    // less than zero?
  346.     asm xor bh,bh        // overflow, clear pixel
  347.     not_negative1:
  348.  
  349.     asm mov es:[di],bx    // store back to 'alpha'
  350.         // now composite with texture, directly to 'vram'
  351.     asm    add bx,fs:[di]    // pixelScale=192, textureScale=64
  352.     asm     mov gs:[di],bx    // so max=255, no overflow
  353.  
  354.     asm sub di,2
  355.     asm jnc composite
  356.     asm pop ds
  357. }
  358.  
  359.  
  360. //||||||||||||||||||||||||||||||||||
  361. //||| 3D ROTATION ALONG Y,Z AXIS |||
  362. //||||||||||||||||||||||||||||||||||
  363. void    do_3D_transformation()
  364. {
  365.     asm    mov     bx,[rx]
  366.     asm    shl    bx,1
  367.     asm    mov    ax,sinf[bx]
  368.     asm    mov    bx,cosf[bx]
  369.     asm    mov    [xsin],ax
  370.     asm    mov    [xcos],bx
  371.  
  372.     asm    mov     bx,[ry]
  373.     asm    shl    bx,1
  374.     asm    mov    ax,sinf[bx]
  375.     asm    mov    bx,cosf[bx]
  376.     asm    mov    [ysin],ax
  377.     asm    mov    [ycos],bx
  378.  
  379.     // transform vertices
  380.     asm    lea    di,[pt]
  381.     asm    lea    si,[object]
  382.     asm    mov    cx,MATRIX3D_RESOLUTION
  383.     asm    mov    ax,[VERTEX]
  384.     asm    mov    [a],ax
  385.  
  386. xform3D:
  387.     // X-axis rotate
  388.     //temp_y= (*ypt * cosf[xdeg] + *zpt * sinf[xdeg]) >> 7;
  389.     //temp_z= (*zpt * cosf[xdeg] - *ypt * sinf[xdeg]) >> 7;
  390.     asm mov ax,[si+2]
  391.     asm imul [xcos]
  392.     asm mov bx,dx
  393.     asm mov cx,ax
  394.  
  395.     asm mov ax,[si+4]
  396.     asm imul [xsin]
  397.     asm add cx,ax
  398.     asm adc bx,dx
  399.  
  400.     asm shrd cx,bx,MATRIX3D_RESOLUTION
  401.     asm mov [temp_y],cx
  402.  
  403.  
  404.     asm mov ax,[si+4]
  405.     asm imul [xcos]
  406.     asm mov bx,dx
  407.     asm mov cx,ax
  408.  
  409.     asm mov ax,[si+2]
  410.     asm imul [xsin]
  411.     asm sub cx,ax
  412.     asm sbb bx,dx
  413.  
  414.     asm shrd cx,bx,MATRIX3D_RESOLUTION
  415.     asm mov [temp_z],cx
  416.  
  417.  
  418.     // Y-axis rotate
  419.     //temp_x= (*xpt * cosf[ydeg] - *zpt * sinf[ydeg]) >> 7;
  420.     //temp_z= (*xpt * sinf[ydeg] + *zpt * cosf[ydeg]) >> 7;
  421.     asm mov ax,[si]
  422.     asm imul [ycos]
  423.     asm mov bx,dx
  424.     asm mov cx,ax
  425.  
  426.     asm mov ax,[temp_z]
  427.     asm imul [ysin]
  428.     asm sub cx,ax
  429.     asm sbb bx,dx
  430.  
  431.     asm shrd cx,bx,MATRIX3D_RESOLUTION
  432.     asm mov [temp_x],cx
  433.  
  434.  
  435.     asm mov ax,[si]
  436.     asm imul [ysin]
  437.     asm mov bx,dx
  438.     asm mov cx,ax
  439.  
  440.     asm mov ax,[temp_z]
  441.     asm imul [ycos]
  442.     asm add cx,ax
  443.     asm adc bx,dx
  444.  
  445.     asm shrd cx,bx,MATRIX3D_RESOLUTION
  446.     asm mov [temp_z],cx
  447.  
  448.     asm mov [di+4],cx
  449.  
  450.  
  451.     // Perspective transform
  452.     asm movsx ebx,[temp_z]
  453.     asm add ebx,512
  454.     asm neg ebx
  455.  
  456.     asm movsx eax,[temp_x]
  457.     asm sal eax,9
  458.     asm cdq
  459.     asm idiv ebx
  460.     asm add ax,160
  461.     asm mov [di],ax
  462.  
  463.     asm movsx eax,[temp_y]
  464.     asm sal eax,9
  465.     asm cdq
  466.     asm idiv ebx
  467.     asm add ax,100
  468.     asm mov [di+2],ax
  469.  
  470.     asm    add    si,6
  471.     asm    add    di,8
  472.     asm    dec    [a]
  473.     asm    jz    xformDone
  474.     asm    jmp    xform3D
  475.     xformDone:
  476.  
  477.  
  478.     // transform vertex normals
  479.     asm    lea    di,[vnorm2]
  480.     asm    lea    si,[vnorm]
  481.     asm    mov    cx,MATRIX3D_RESOLUTION
  482.     asm    mov    ax,[VERTEX]
  483.     asm    mov    [a],ax
  484.  
  485. xform3D_vnorm:
  486.  
  487.     // X-axis rotate
  488.     //temp_y= (*ypt * cosf[xdeg] + *zpt * sinf[xdeg]) >> 7;
  489.     //temp_z= (*zpt * cosf[xdeg] - *ypt * sinf[xdeg]) >> 7;
  490.     asm mov ax,[si+2]
  491.     asm imul [xcos]
  492.     asm mov bx,dx
  493.     asm mov cx,ax
  494.     asm mov ax,[si+4]
  495.     asm imul [xsin]
  496.     asm add cx,ax
  497.     asm adc bx,dx
  498.     asm shrd cx,bx,MATRIX3D_RESOLUTION
  499.     asm mov [temp_y],cx
  500.  
  501.     asm mov ax,[si+4]
  502.     asm imul [xcos]
  503.     asm mov bx,dx
  504.     asm mov cx,ax
  505.     asm mov ax,[si+2]
  506.     asm imul [xsin]
  507.     asm sub cx,ax
  508.     asm sbb bx,dx
  509.     asm shrd cx,bx,MATRIX3D_RESOLUTION
  510.     asm mov [temp_z],cx
  511.  
  512.  
  513.     // Y-axis rotate
  514.     //temp_x= (*xpt * cosf[ydeg] - *zpt * sinf[ydeg]) >> 7;
  515.     //temp_z= (*xpt * sinf[ydeg] + *zpt * cosf[ydeg]) >> 7;
  516.     asm mov ax,[si]
  517.     asm imul [ycos]
  518.     asm mov bx,dx
  519.     asm mov cx,ax
  520.     asm mov ax,[temp_z]
  521.     asm imul [ysin]
  522.     asm sub cx,ax
  523.     asm sbb bx,dx
  524.     asm shrd cx,bx,MATRIX3D_RESOLUTION
  525.     asm mov [temp_x],cx
  526.  
  527.     asm mov ax,[si]
  528.     asm imul [ysin]
  529.     asm mov bx,dx
  530.     asm mov cx,ax
  531.     asm mov ax,[temp_z]
  532.     asm imul [ycos]
  533.     asm add cx,ax
  534.     asm adc bx,dx
  535.     asm shrd cx,bx,MATRIX3D_RESOLUTION
  536.     asm mov [temp_z],cx
  537.  
  538.  
  539.     asm mov ax,[temp_x]
  540.     asm mov [di],ax
  541.     asm mov ax,[temp_y]
  542.     asm mov [di+2],ax
  543.     asm mov ax,[temp_z]
  544.     asm mov [di+4],ax
  545.  
  546.     asm    add    si,6
  547.     asm    add    di,6
  548.     asm    dec    [a]
  549.     asm    jz    xformDone_vnorm
  550.     asm    jmp    xform3D_vnorm
  551.     xformDone_vnorm:
  552.  
  553.  
  554.     if( (ry+=ry_dir)>=MAX ) ry=0;
  555.     if( (rx+=rx_dir)>=MAX ) rx=0;
  556.     if(!wait2--) { wait2=60; ry_dir=random(5)+1; rx_dir=random(5); }
  557.  
  558.  
  559.  
  560. }
  561.  
  562. //|||||||||||||||||||||||||||||||||||||||||
  563. //||| BACKFACE ELIMINATION AND BIN SORT |||
  564. //|||||||||||||||||||||||||||||||||||||||||
  565. void    sort_facets()
  566. {
  567.     asm mov fs,[order]
  568.  
  569.     asm mov cx,[FACE]
  570.     asm lea bx,[facet]
  571.     bin_sort:
  572.     asm mov si,[bx]        // facet[][0]
  573.     asm mov eax,dword ptr [si]
  574.     asm mov dword ptr [p1x],eax
  575.     asm mov bp,[si+4]
  576.  
  577.     asm mov si,[bx+2]    // facet[][1]
  578.     asm mov eax,dword ptr [si]
  579.     asm mov dword ptr [p2x],eax
  580.  
  581.     asm mov si,[bx+4]    // facet[][2]
  582.     asm mov eax,dword ptr [si]
  583.     asm mov dword ptr [p3x],eax
  584.  
  585.         // BACKFACE CULLING
  586.         asm mov ax,[p2x]
  587.         asm mov dx,[p3x]
  588.         asm mov di,[p2y]
  589.         asm mov si,[p3y]
  590.         asm sub ax,[p1x]    // ax=v1
  591.         asm sub dx,[p1x]    // dx=w1
  592.         asm sub di,[p1y]    // di=v2
  593.         asm sub si,[p1y]    // si=w2
  594.         asm imul ax,si
  595.         asm imul di,dx
  596.         asm sub ax,di        // ax=v1*w2-v2*w1
  597.         asm cmp ax,0
  598.         asm jge facet_is_hidden
  599.         // BACKFACE CULL COMPLETE
  600.  
  601.     asm add bp,NBINS/2    // shift z-origin, so all z's are +ve
  602.     asm shl bp,BINSIZELOG2+1
  603.     asm mov ax,fs:[bp]    // get facet count in bin
  604.     asm cmp ax,BINSIZE-1
  605.     asm jge bin_is_full
  606.     asm inc fs:[bp]        // add facet to bin
  607.     asm add ax,ax        // word access
  608.     asm add bp,ax
  609.     asm mov fs:[bp+2],bx    // save facet address instead of index
  610.     bin_is_full:
  611.  
  612.     facet_is_hidden:
  613.     asm add bx,6
  614.     asm dec cx
  615.     asm jz sort_done
  616.     asm jmp bin_sort
  617.     sort_done:
  618. }
  619.  
  620.  
  621. //|||||||||||||||||||||||||||||||||||||||||||||||||||||
  622. //||| INITIALIZE GRAPHICS MODE AND LOAD VGA PALETTE |||
  623. //|||||||||||||||||||||||||||||||||||||||||||||||||||||
  624. void    graphics()
  625. {
  626.     asm    mov    ax,13h
  627.     asm    int    10h
  628.  
  629.     #ifndef BMP
  630.     asm mov dx,0x3c8
  631.     asm xor ax,ax
  632.     asm out dx,al
  633.     asm inc dx
  634.     asm mov cx,768
  635.     asm lea si,[phong]
  636.     asm cld
  637.     asm rep outsb
  638.     #else
  639.     asm mov dx,0x3c8
  640.     asm xor ax,ax
  641.     asm out dx,al
  642.     asm inc dx
  643.     asm mov cx,768
  644.     asm lea si,[palette]
  645.     asm cld
  646.     asm rep outsb
  647.     #endif
  648.  
  649.  
  650.     for(a=0; a<200; a++)
  651.     y_offset[a]=a*320;
  652.  
  653.     #ifndef BMP
  654.     asm mov ax,0xa000
  655.     asm mov es,ax
  656.     asm lea si,[phong_curve]
  657.     asm mov di,192
  658.     draw_phong_curve:
  659.     asm lodsw
  660.     asm mov bx,ax
  661.     asm add bx,bx
  662.     asm mov bx,y_offset[bx]
  663.     asm mov byte ptr es:[di+bx],255
  664.     asm mov ax,192
  665.     asm sub ax,di
  666.     asm mov es:[di+320*195],al
  667.     asm mov es:[di+320*196],al
  668.     asm mov es:[di+320*197],al
  669.     asm mov es:[di+320*198],al
  670.     asm dec di
  671.     asm jnz draw_phong_curve
  672.  
  673.     getch();
  674.     #endif
  675.  
  676.     // clear bin table
  677.     asm mov es,[order]
  678.     asm xor di,di
  679.     asm xor eax,eax
  680.     asm mov cx,64000/4
  681.     asm rep stosd
  682.     // clear vbuffer
  683.     asm mov es,[vbuffer]
  684.     asm xor di,di
  685.     asm xor eax,eax
  686.     asm mov cx,64000/4
  687.     asm rep stosd
  688. }
  689. //-----------------
  690. void    text()
  691. {
  692.     asm    mov    ax,3
  693.     asm    int    10h
  694. }
  695.  
  696. //|||||||||||||||||||||||||||||||||||||||||||
  697. //||| PHONG SHADE INTENSITY LOOK-UP TABLE |||
  698. //|||||||||||||||||||||||||||||||||||||||||||
  699. void    make_phong_table()
  700. {
  701.     int iL;
  702.     float cos_theta;
  703.  
  704. for(a=0; a<=pixelScale; a++)
  705. {
  706. cos_theta=cos((pixelScale-a)/pixelScale*90.0*rad);
  707.  
  708. iL=(float)(AMBIENCE
  709.       +DIFFUSE*cos_theta
  710.       +SPECULIAR_COEF*pow(cos_theta,SPECULIAR_EXPONENT))*pixelScale;
  711.  
  712. phong[a*3+0]=palette[iL*3+0];    // map from linear external palette
  713. phong[a*3+1]=palette[iL*3+1];    // to phong palette using
  714. phong[a*3+2]=palette[iL*3+2];    // illumination value, iL.
  715.  
  716. phong_curve[a]=pixelScale-iL;
  717. }
  718.  
  719.  
  720. for(a=192*3; a<256*3; a++)
  721. phong[a]=palette[a];
  722.  
  723. for(a=0; a<arccos_size; a++)
  724. arccos[a]=acos(-2.0*a/arccos_size+1.0)*(pixelScale/M_PI);
  725.  
  726. }
  727.  
  728. //||||||||||||||||||||||||||||||||||||||||||||||||||||||
  729. //||| LOAD OBJECT VERTICES,FACETS AND VERTEX NORMALS |||
  730. //||||||||||||||||||||||||||||||||||||||||||||||||||||||
  731. void    load_object()
  732. {
  733.     FILE *f;
  734.  
  735.     f=fopen(VERTEXfile,"rb");
  736.     fseek(f,-2L,SEEK_END);
  737.     fread(&VERTEX,1,2,f);    // Get number of vertices
  738.     if(VERTEX>MAXVERTEX) { VERTEX=MAXVERTEX; }
  739.     fseek(f,0,SEEK_SET);
  740.     fread(object,1,VERTEX*3*2,f);
  741.     fclose(f);
  742.  
  743.     f=fopen(FACETfile,"rb");
  744.     fseek(f,-2L,SEEK_END);
  745.     fread(&FACE,1,2,f);    // Get number of facets
  746.     if(FACE>MAXFACE) { FACE=MAXFACE; }
  747.     fseek(f,0,SEEK_SET);
  748.     fread(facet,1,FACE*3*2,f);
  749.     fclose(f);
  750.  
  751.     f=fopen(VNORMfile,"rb");
  752.     fread(vnorm32,1,VERTEX*3*4,f);
  753.     fclose(f);
  754.  
  755.     f=fopen(PALfile,"rb");
  756.     fread(palette,1,768,f);
  757.     fclose(f);
  758.  
  759.     printf("\n%d vertices loaded.\n%d facets loaded\n",VERTEX,FACE);
  760.  
  761.     // changing 'facet[][]' to hold vertex address instead of vertex no.
  762.     for(a=0; a<FACE; a++)
  763.     {
  764.     temp_ptr=&pt[facet[a][0]][0];
  765.     asm mov ax,[temp_ptr]
  766.     asm mov [temp],ax
  767.     facet[a][0]=temp;
  768.  
  769.     temp_ptr=&pt[facet[a][1]][0];
  770.     asm mov ax,[temp_ptr]
  771.     asm mov [temp],ax
  772.     facet[a][1]=temp;
  773.  
  774.     temp_ptr=&pt[facet[a][2]][0];
  775.     asm mov ax,[temp_ptr]
  776.     asm mov [temp],ax
  777.     facet[a][2]=temp;
  778.     }
  779.  
  780.     for(a=0; a<VERTEX; a++)
  781.     {
  782.     vnorm[a][X]=vnorm32[a][X];
  783.     vnorm[a][Y]=vnorm32[a][Y];
  784.     vnorm[a][Z]=vnorm32[a][Z];
  785.     }
  786. }
  787. //-----------------
  788. void    load_backdrop()
  789. {
  790.     asm mov ax,0x3d00
  791.     asm lea dx,[backdrop_file]
  792.     asm int 0x21
  793.     asm mov bp,ax
  794.  
  795.     asm mov bx,bp
  796.     asm mov ax,0x4200
  797.     asm xor cx,cx
  798.     asm mov dx,1078
  799.     asm int 0x21
  800.  
  801.     asm mov bx,bp
  802.     asm mov ah,0x3f
  803.     asm mov cx,64000
  804.     asm xor dx,dx
  805.     asm push ds
  806.     asm mov ds,[backdrop]
  807.     asm int 0x21
  808.     asm pop ds
  809.  
  810.     asm mov bx,bp
  811.     asm mov ah,0x3e
  812.     asm int 0x21
  813.  
  814.     //post process backdrop, uses last 64 colors in palette
  815.     asm mov es,[backdrop]
  816.     asm xor di,di
  817.     asm mov cx,64000
  818.     post_process:
  819.     //asm add byte ptr es:[di],192
  820.     asm inc di
  821.     asm loop post_process
  822.  
  823.     #ifdef BLACK_BACKDROP
  824.     asm mov es,[backdrop]
  825.     asm xor di,di
  826.     asm mov al,BLACK_VALUE
  827.     asm mov cx,64000
  828.     //asm rep stosb
  829.     #endif
  830.  
  831. }
  832. //---------------------
  833. void load_texture()
  834. {
  835.     // LOAD OBJECT TEXTURE
  836.     asm mov ax,0x3d00
  837.     asm lea dx,[texture_file]
  838.     asm int 0x21
  839.     asm mov bp,ax
  840.  
  841.     #ifdef BMP
  842.     asm mov bx,bp
  843.     asm mov ax,0x4200
  844.     asm xor cx,cx
  845.     asm mov dx,54
  846.     asm int 0x21
  847.  
  848.     asm mov bx,bp
  849.     asm mov ah,0x3F
  850.     asm mov cx,1024
  851.     asm lea dx,[bmp_palette]
  852.     asm int 0x21
  853.     #endif
  854.  
  855.     asm mov bx,bp
  856.     asm mov ah,0x3f
  857.     asm mov cx,0x8000
  858.     asm xor dx,dx
  859.     asm push ds
  860.     asm mov ds,[texture]
  861.     asm int 0x21
  862.     asm pop ds
  863.     asm mov bx,bp
  864.     asm mov ah,0x3f
  865.     asm mov cx,0x8000
  866.     asm mov dx,0x8000
  867.     asm push ds
  868.     asm mov ds,[texture]
  869.     asm int 0x21
  870.     asm pop ds
  871.  
  872.     asm mov bx,bp
  873.     asm mov ah,0x3e
  874.     asm int 0x21
  875.  
  876.  
  877.     asm mov es,[texture]
  878.     asm xor di,di
  879.     asm mov bx,3
  880.     maximize:
  881.     asm xor ax,ax
  882.     asm mov al,es:[di]
  883.     asm mul bl
  884.     asm shr ax,2
  885.     asm mov es:[di],al
  886.  
  887.     asm inc di
  888.     asm jnz maximize
  889.  
  890.     #ifndef BMP
  891.     // post process texture
  892.     asm mov es,[texture]
  893.     asm mov bx,1
  894.     asm mov cl,11
  895.     ntimes:
  896.     asm xor di,di
  897.     asm xor dx,dx
  898.     post_process2:
  899.     asm xor ax,ax
  900.     asm xor dx,dx
  901.  
  902.     asm mov dl,es:[di]
  903.     asm add ax,dx
  904.     asm add ax,dx
  905.     asm add ax,dx
  906.     asm mov dl,es:[di+1]
  907.     asm add ax,dx
  908.     asm mov dl,es:[di-1]
  909.     asm add ax,dx
  910.     asm mov dl,es:[di+256]
  911.     asm add ax,dx
  912.     asm mov dl,es:[di-256]
  913.     asm add ax,dx
  914.  
  915.     asm mov dl,es:[di-257]
  916.     asm add ax,dx
  917.     asm mov dl,es:[di-255]
  918.     asm add ax,dx
  919.     asm mov dl,es:[di+257]
  920.     asm add ax,dx
  921.     asm mov dl,es:[di+255]
  922.     asm add ax,dx
  923.  
  924.     asm div cl
  925.  
  926.     asm mov es:[di],al
  927.     asm inc di
  928.     asm jnz post_process2
  929.  
  930.     asm dec bx
  931.     asm jnz ntimes
  932.     #else
  933.  
  934.     n=0;
  935.     for(a=0; a<1024; a+=4)
  936.     {
  937.     palette[n]=bmp_palette[a+2]>>2;
  938.     palette[n+1]=bmp_palette[a+1]>>2;
  939.     palette[n+2]=bmp_palette[a]>>2;
  940.  
  941.     n+=3;
  942.     }
  943.     #endif
  944. }
  945. //---------------------
  946. void init3d_10bits()
  947. {
  948.     int     degree;
  949.  
  950.     for(degree=0; degree<MAX; degree++)
  951.     {
  952.     sinf[degree]=sin(360.0/MAX*degree*rad) * pow(2,MATRIX3D_RESOLUTION);
  953.     cosf[degree]=cos(360.0/MAX*degree*rad) * pow(2,MATRIX3D_RESOLUTION);
  954.     }
  955.  
  956.     for(degree=-128; degree<128; degree++)
  957.     asine[degree+128]=255.0*( (M_PI/2+asin(degree/128.0)) /(M_PI/1));
  958. }
  959. //--------------------
  960. void    debug()
  961. {
  962.     for(a=0; a<NBINS; a++)
  963.     {}
  964. }
  965.  
  966. //|||||||||||||||||||||||||||||||||||||||||||
  967. //||| Compute texture domain coord t(u,v) |||
  968. //||| from vertex normals using inverse   |||
  969. //||| polar-coordinates                   |||
  970. //|||||||||||||||||||||||||||||||||||||||||||
  971. void apply_env_map_coord()
  972. {
  973.     /*vnormal=&vnorm2[0][X];
  974.  
  975.     for(a=0; a<VERTEX; a++)
  976.     {
  977.     // environment mapping
  978.     texture_x=asine[*vnormal+128];
  979.     texture_y=asine[*(vnormal+1)+128];
  980.     //texture_x=*vnormal+128;
  981.     //texture_y=*(vnormal+1)+128;
  982.     pt[a][3]=(texture_y<<8)+texture_x;
  983.     vnormal+=3;
  984.     }*/
  985.  
  986.     asm lea si,[vnorm2]
  987.     asm lea di,[pt]
  988.     asm add di,6
  989.     asm mov cx,[VERTEX]
  990.     env_map:
  991.     asm mov bx,[si]
  992.     asm mov al,asine[bx+128]
  993.     asm mov bx,[si+2]
  994.     asm mov ah,asine[bx+128]
  995.  
  996.     asm mov [di],ax
  997.     asm add si,6
  998.     asm add di,8
  999.     asm dec cx
  1000.     asm jnz env_map
  1001.  
  1002.  
  1003. }
  1004.  
  1005. //||||||||||||||||||||||||||||||||||||||
  1006. //||| DRAW ALL FACETS STORED IN BINS |||
  1007. //||||||||||||||||||||||||||||||||||||||
  1008. void    draw_object_envmap()
  1009. {
  1010.     //draw facets onto buffer
  1011.     asm mov fs,[order]
  1012.     asm mov gs,[texture]
  1013.     for(c=NBINS-1; c>=0; c--) // start with the furthest bin
  1014.     {
  1015.     asm mov si,[c]
  1016.     asm shl si,BINSIZELOG2+1
  1017.     asm mov [current_bin],si
  1018.     asm mov ax,fs:[si]    // order[c][0]=number of facets in this bin
  1019.     asm mov [d],ax
  1020.     asm mov fs:[si],0    // clear bin
  1021.  
  1022.     order_loop:
  1023.     asm cmp [d],0        // all facets in bin drawn?
  1024.     asm jg  bin_not_empty    // not yet, bin still not empty
  1025.     asm jmp order_done
  1026.     bin_not_empty:
  1027.     asm mov ax,[d]
  1028.     asm dec [d]        // take another facet out of bin
  1029.     asm mov si,[current_bin]
  1030.     asm add ax,ax
  1031.     asm add si,ax
  1032.     asm mov si,fs:[si]    // facet start address=order[c][d+1];
  1033.  
  1034.     // GET VERTICES OF CURENT FACET
  1035.     asm mov bx,[si]        // facet[][0]
  1036.     asm mov di,[si+2]    //ax=vv1=facet[][1]
  1037.     asm mov si,[si+4]    //ax=vv2=facet[][2]
  1038.  
  1039.     // bx=vertex1, di=vertex2, si=vertex3
  1040.  
  1041.     // SORT FACET EDGES
  1042.     // make p1 the top-most point
  1043.     asm mov ax,[bx+2]
  1044.     asm cmp ax,[di+2]
  1045.     asm jle ok1
  1046.     asm xchg bx,di
  1047.     ok1:
  1048.     asm mov ax,[bx+2]
  1049.     asm cmp ax,[si+2]
  1050.     asm jle ok2
  1051.     asm xchg bx,si
  1052.     ok2:
  1053.     // make p2 the left-most point
  1054.     asm mov ax,[di]
  1055.     asm cmp ax,[si]
  1056.     asm jle ok3
  1057.     asm xchg di,si
  1058.     ok3:
  1059.  
  1060.     asm mov [p1x],bx    // vertex #1 offset
  1061.     asm mov [p2x],di    // vertex #2 offset
  1062.     asm mov [p3x],si    // vertex #3 offset
  1063.  
  1064.         // BUILD EDGE TABLE
  1065.         asm mov [top],200
  1066.         asm mov [bot],0
  1067.         asm mov bx,[p1x]    // vertex offset
  1068.         asm mov di,[p3x]
  1069.         asm mov cx,[bx]        //p1x
  1070.         asm mov bp,[bx+2]    //p1y
  1071.         asm mov ax,[di]        //p3x
  1072.         asm mov dx,[di+2]    //p3y
  1073.         asm mov si,[bx+6]    //i1
  1074.         asm mov di,[di+6]    //i3
  1075.         asm mov [flipflop],RITE_ENTRY
  1076.         asm call make_edge_env // construct edge connecting p1<->p3
  1077.  
  1078.         asm mov bx,[p1x]
  1079.         asm mov di,[p2x]
  1080.         asm mov cx,[bx]
  1081.         asm mov bp,[bx+2]
  1082.         asm mov ax,[di]
  1083.         asm mov dx,[di+2]
  1084.         asm mov si,[bx+6]
  1085.         asm mov di,[di+6]
  1086.         asm mov [flipflop],LEFT_ENTRY
  1087.         asm call make_edge_env // construct edge connecting p1<->p2
  1088.  
  1089.         asm mov bx,[p2x]
  1090.         asm mov di,[p3x]
  1091.         asm mov bp,[bx+2]
  1092.         asm mov dx,[di+2]
  1093.  
  1094.         asm cmp bp,dx
  1095.         asm jl  ok4
  1096.         asm je  edge_table_done
  1097.         asm xchg bx,di
  1098.         asm xchg bp,dx
  1099.         asm mov [flipflop],RITE_ENTRY
  1100.         ok4:
  1101.         asm mov cx,[bx]
  1102.         asm mov ax,[di]
  1103.         asm mov si,[bx+6]
  1104.         asm mov di,[di+6]
  1105.         asm call make_edge_env // construct edge connecting p2<->p3
  1106.  
  1107.         edge_table_done:
  1108.         asm mov ax,[top]
  1109.         asm mov bx,[bot]
  1110.         asm cmp ax,START_SCANLINE
  1111.         asm jge top_ok
  1112.         asm mov ax,START_SCANLINE
  1113.         top_ok:
  1114.         asm cmp bx,END_SCANLINE
  1115.         asm jle bot_ok
  1116.         asm mov bx,END_SCANLINE
  1117.         bot_ok:
  1118.         asm mov cx,bx
  1119.         asm sub cx,ax
  1120.         asm jc  skip_facet    // skip if length is negative
  1121.         asm jz  skip_facet    // skip if length is zero
  1122.         asm call draw_one_facet_env
  1123.         skip_facet:
  1124.         asm jmp order_loop
  1125.         order_done:
  1126.     }
  1127. }
  1128. //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  1129. //||| FILL DOUBLE-EDGE TABLE USING DIGITAL DIFFERENTIAL ANALYSIS |||
  1130. //||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  1131. void calc_slope()
  1132. {
  1133.     asm make_edge_env:
  1134.     asm mov bx,dx
  1135.     asm sub bx,bp    // ysize=ye-ys;
  1136.     asm jnz okok
  1137.     asm jmp done
  1138.     okok:
  1139.     asm mov [ysize],bx
  1140.  
  1141.     asm mov bx,bp
  1142.     asm shl bx,3          // each entry is 8 bytes
  1143.     asm add bx,offset [slope] // idx=ys<<3+&slope;
  1144.     asm add bx,[flipflop]      // left/rite entry selector
  1145.  
  1146.     // record top and bottom of current edge
  1147.     asm cmp [top],bp    //if(top>ys) top=ys;
  1148.     asm jle top_nochange
  1149.     asm mov [top],bp
  1150.     top_nochange:
  1151.     asm cmp [bot],dx    //if(bot<ye) bot=ye;
  1152.     asm jge bot_nochange
  1153.     asm mov [bot],dx
  1154.     bot_nochange:
  1155.  
  1156.     asm mov dx,cx
  1157.     asm shl edx,7+16    // x1=xs<<7; 7-bit becoz x can be 0..320
  1158.  
  1159.     asm sub ax,cx
  1160.     asm shl ax,7
  1161.     asm mov cx,[ysize]
  1162.     asm cwd
  1163.     asm idiv cx      // xadd=128*(xe-xs)/ysize;
  1164.     asm push ax
  1165.  
  1166.  
  1167.     asm mov ax,di
  1168.     asm xor al,al
  1169.     asm mov dx,si
  1170.     asm xor dl,dl
  1171.     asm sub ax,dx
  1172.     asm cwd
  1173.     asm idiv cx
  1174.     asm shl eax,16    // DDAty
  1175.  
  1176.     asm mov ax,di
  1177.     asm xor ah,ah
  1178.     asm mov dx,si
  1179.     asm xor dh,dh
  1180.     asm sub ax,dx
  1181.     asm shl ax,8
  1182.     asm cwd
  1183.     asm idiv cx
  1184.     asm mov edi,eax    // DDAtx
  1185.  
  1186.     asm mov ax,si
  1187.     asm shl ax,8
  1188.     asm mov [texture_x],ax
  1189.     asm mov ax,si
  1190.     asm xor al,al
  1191.     asm mov [texture_y],ax
  1192.  
  1193.     asm pop ax
  1194.     asm shl eax,16
  1195.  
  1196.     fill_slope_table:
  1197.     asm mov dh,byte ptr [texture_y+1]
  1198.     asm mov dl,byte ptr [texture_x+1]
  1199.     asm mov [bx],edx
  1200.     asm add bx,8
  1201.     asm add edx,eax
  1202.     asm add dword ptr [texture_x],edi
  1203.  
  1204.     asm dec cx
  1205.     asm jnz fill_slope_table
  1206.     done:;
  1207.     asm ret
  1208. }
  1209. //||||||||||||||||||||||||||||
  1210. //||| FILL ONE PHONG FACET |||
  1211. //||||||||||||||||||||||||||||
  1212. void    fillshape_env()
  1213. {
  1214.  
  1215. asm draw_one_facet_env:
  1216. asm mov bx,ax    // bx=top
  1217. asm add bx,bx    // word access
  1218. asm mov bp,y_offset[bx]
  1219. asm shl bx,2    // qword access
  1220. asm add bx,offset [slope]
  1221. asm mov es,[vbuffer]
  1222.  
  1223. // fill scanlines in poly from top to bottom
  1224. fill_loop:
  1225. asm    bswap ecx
  1226.  
  1227.     // left entry
  1228.     asm mov cx,[bx]      //angle1
  1229.     asm mov di,[bx+2] //x1
  1230.     asm shr di,7      //remove fix-point
  1231.     // rite entry
  1232.     asm mov ax,[bx+4] //angle2
  1233.     asm mov si,[bx+6] //x2
  1234.     asm shr si,7      //remove fix-point
  1235.     asm add bx,8      //next entry...
  1236.  
  1237.     // let's go from left to right
  1238.     asm cmp si,di        //xsize=x2-x1
  1239.     asm jnz proceed        //xsize=0?
  1240.     asm jmp far ptr done_one_scanline //xsize is zero, no fill done
  1241.     proceed:
  1242.     asm jnc no_exchange    //xsize<0?
  1243.     asm xchg si,di
  1244.     asm xchg cx,ax        //switch angle1,angle2
  1245.     no_exchange:
  1246.     asm sub si,di
  1247.  
  1248.     asm push ax
  1249.     asm sub al,cl
  1250.     asm shl ax,8
  1251.     asm cwd
  1252.     asm idiv si
  1253.     asm shl eax,16
  1254.  
  1255.     asm pop ax
  1256.     asm sub ah,ch
  1257.     asm xor al,al
  1258.     asm cwd
  1259.     asm idiv si
  1260.  
  1261.     asm push ds
  1262.     asm mov ds,[texture]
  1263.  
  1264.     asm xor dx,dx
  1265.     asm mov dh,ch
  1266.     asm mov [texture_x],dx
  1267.     asm mov dh,cl
  1268.     asm mov [texture_y],dx
  1269.  
  1270.     asm add di,bp
  1271.     asm push bx
  1272.  
  1273.     envmap_innerloop:
  1274.     asm mov bl,byte ptr [texture_x+1]
  1275.     asm mov bh,byte ptr [texture_y+1]
  1276.     asm mov dl,gs:[bx]
  1277.  
  1278.     asm mov es:[di],dl
  1279.     asm inc di
  1280.  
  1281.     asm add dword ptr [texture_x],eax
  1282.     asm dec si
  1283.     asm jnz envmap_innerloop
  1284.  
  1285.     asm pop bx
  1286.     asm pop ds
  1287.     done_one_scanline:
  1288.     asm add bp,320    //start of next scanline
  1289.  
  1290. asm bswap ecx
  1291. asm dec cx
  1292. asm jz facet_filled
  1293. asm jmp fill_loop
  1294. facet_filled:
  1295. asm ret
  1296.  
  1297.     asm innerloop_start:
  1298.  
  1299.     asm mov bl,byte ptr [texture_x+1]
  1300.     asm mov bh,byte ptr [texture_y+1]
  1301.     asm mov al,gs:[bx]
  1302.     asm add dword ptr [texture_x],edx
  1303.     asm mov es:[di],al
  1304.     asm inc di
  1305.  
  1306.     asm innerloop_end:
  1307. }
  1308.